var http = require('http');
const jwt = require('jsonwebtoken');
import configFile from './config';

import app from './app';
import mongodbHandle from './handle/mongodbHandle'
import routeHandle from './handle/routeHandle'
import rankHandle from './handle/rankHandle';
import * as cluster from 'cluster'
import * as os from 'os'
import redisHandle from './handle/redisHandle';
import utils from './serverCore/utils';
var cp = require('child_process');
import * as child_process from 'child_process';
var cpuCount = os.cpus().length;
import { nbase64 } from 'core/utils/newEnco';

import { GameRouteData, routeApiConfig } from 'core/utils/localApi';
import moment = require('moment');
import { base64 } from 'core/utils/enco';
import gameHandle from './handle/gameHandle';


if (process.argv.length >= 2 && configFile[process.argv[2]]) {
    app.env = process.argv[2]
    app.config = configFile[process.argv[2]]
    app.gameName = configFile.gameName
} else {
    app.env = 'dev'
    app.config = configFile['dev']
    app.gameName = configFile.gameName
}

let getResData = async (data, code) => {
    let date = new Date()
    data.time = date.getTime()
    data.version = app.version
    data.dtime = moment().valueOf()
    if (data.data && code) {
        let dataStr = JSON.stringify(data.data)
        let key = utils.getHmac(code + "qihuan", dataStr)
        data.key = key
        data.dataStr = dataStr
        delete data.data
    }
    data = JSON.stringify(data)

    if (app.env == 'pro' || app.env == 'demo') {
        data = base64.encode(data)
    }
    return data
}

var httpapp = async (req, res) => {
    res.setHeader('Access-Control-Allow-Credentials', 'true');
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
    res.setHeader("Access-Control-Allow-Headers", "X-Requested-With,cache-control,content-type,hash-referer,authorization,testclient");

    let reqs = req.url.split('/')
    let api = reqs[reqs.length - 2]
    let reqUrl = reqs[reqs.length - 1]
    //升级维护中
    let testclient = req.headers.testclient
    if (app.serverState !== 0) {

        if (req.method === 'GET' || req.method === 'get' || req.method === 'post' || req.method === 'POST') {
            if (!testclient) {
                res.end(
                    await getResData({
                        err: 110,
                        data: app.stateText
                    }, null)
                )
                return
            }
        }
    }

    if (req.method === 'GET' || req.method === 'get') {

    } else if (req.method === 'POST') {
        const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
        var data = "";
        req.on("data", (chunk) => {
            data += chunk;
        })
        req.on("end", async () => {
            if (reqUrl == "leNotifycharge") {
                try {
                    if (app.env == 'demo') {
                        console.log('leNotifycharge', data)
                    }
                    let dataJson = {}
                    data.split('&').forEach(item => {
                        let d = item.split('=')
                        dataJson[d[0]] = d[1]
                    });
                    let resData = await routeHandle("leNotifycharge", dataJson, null)
                    res.end(JSON.stringify(resData.data))
                } catch (e) {
                    res.end()
                }
                return
            }

            let token = req.headers.authorization
            let dataJson
            if (api == 'api') {
                try {
                    if (app.env == 'pro' || app.env == 'demo') {
                        data = base64.decode(data)
                    }
                    dataJson = JSON.parse(data);
                } catch (e) {
                    res.end(
                        await getResData({
                            err: 105,
                            data: e.message
                        }, null)
                    )
                }

                let route = dataJson.r
                if (reqUrl == "charge") {
                    route = reqUrl
                }
                dataJson.testclient = testclient
                dataJson.ipAddress = ip
                if (token) {
                    jwt.verify(token, "secretkey", async (err, decode) => {
                        if (!err) {
                            let resData = await routeHandle(route, dataJson, decode)
                            res.end(await getResData(resData, dataJson.c))
                        } else {
                            let resData = await routeHandle(route, dataJson, null)
                            res.end(await getResData(resData, dataJson.c))
                        }
                    })
                } else {
                    let resData = await routeHandle(route, dataJson, null)
                    res.end(await getResData(resData, dataJson.c))
                }
            } else {
                res.end()
            }
        })
    } else {
        res.end()
    }
};


let forkInit = async () => {
    app.type = 'worker'
    console.log('worker:' + cluster.worker.id)
    routeApiConfig.isClient = false
    await redisHandle.init('worker:' + cluster.worker.id)
    await mongodbHandle.init('worker:' + cluster.worker.id)
    // if (app.env == 'demo' || app.env == 'dev') {
    //     await mongodbHandle.initTest('mongodb://root:123456789qwe@14.22.114.20:27017', 'viruspro')
    // }
    let server = http.createServer(httpapp);
    server.listen(app.config.port, (err) => {
        console.log(`worker:${cluster.worker.id} 服务器环境: ${app.env} 端口:${app.config.port}`)
    });
    // await rankHandle.init()
    process.on('message', function (msg) {
        if (msg.message == "setVersion") {
            console.log("setVersion", msg.version)
            app.version = msg.version

        } else if (msg.message == "updatePlayer") {
            for (let i = 0; i < app.playerSessionForks.length; i++) {
                let fork = app.playerSessionForks[i].fork
                app.sendMessage(fork, 'updateAllPlayer', null, null)
            }
        } else if (msg.message == "updatePlayerYearVip") {
            for (let i = 0; i < app.playerSessionForks.length; i++) {
                let fork = app.playerSessionForks[i].fork
                app.sendMessage(fork, 'updatePlayerYearVip', null, msg.pID)
            }
        } else if (msg.message == "setServerState") {
            app.serverState = msg.serverState
            app.stateText = msg.stateText || "服务器在维护中"

        }
    });

    for (var i = 0; i < cpuCount && i < 3; i++) {
        let fork = child_process.fork('./dist/fork.js', [i + "", ...process.argv.slice(2)]);
        fork.on('message', function (msg) {
            if (msg.messageID) {
                let messageID = msg.messageID
                if (app.forkmessageCb[messageID]) {
                    app.forkmessageCb[messageID](msg)
                    delete app.forkmessageCb[messageID]
                }
            } else if (msg.message == "playerAmount") {
                app.playerSessionForks[msg.forkID].amount = msg.playerAmount
                if (msg.pIDs) {
                    for (let i = 0; i < msg.pIDs.length; i++) {
                        let pID = msg.pIDs[i]
                        delete app.playerSessionForksByID[pID]
                    }
                }
            }
        })
        app.playerSessionForks.push({ fork, amount: 0 })
    }
}

let masterInit = async () => {
    app.type = 'master'
    console.log('master主进程')
    await redisHandle.init('master主进程')
    await mongodbHandle.init('master主进程')
    if (app.env == 'demo' || app.env == 'dev') {
        // await mongodbHandle.initTest('mongodb://root:123456789qwe@14.22.114.20:27017', 'darklypro')
    }
    let server = http.createServer(httpapp);
    server.listen(app.config.masterPort);
    console.log(`master 服务器环境: ${app.env} 端口:${app.config.masterPort}`)

    var n = child_process.fork('./dist/arenaAutoMain.js');
    app.arenaFork = n
    n.send({ "message": "version", "version": app.version });
    n.send({ "message": "start", "env": app.env });

    // var csn = cp.fork('./dist/csArenaMain.js');
    // app.csFork = csn
    // csn.send({ "message": "version", "version": app.version });
    // csn.send({ "message": "start", "env": app.env });
    // console.log('启动子进程:' + cpuCount)

    for (var i = 0; i < cpuCount && i < 1; i++) {
        cluster.fork();
    }


    for (const id in cluster.workers) {
        let worker = cluster.workers[id]
        worker.on('message', (message) => {
            if (app.arenaFork && app.arenaFork.send) {
                if (message.message == 'arenaAutoAddPlayer') {
                    app.arenaFork.send({ "message": "arenaAutoAddPlayer", "pID": message.pid });
                } else if (message.message == 'csArenaAddPlayer') {
                    app.csFork.send({ "message": "csArenaAddPlayer", "pID": message.pid, serverID: message.serverID });
                }
            }
        });
    }
    await rankHandle.init()
    await rankHandle.schedule()

}

let start = async () => {
    if (cluster.isMaster) {
        await masterInit()
    } else {
        forkInit()
    }
}

start()

